#include "HttpProtocol.hpp"
#include "TcpServer.hpp"
#include "Socket.hpp"
#include <iostream>
#include <memory>
#include <fstream>
#include <unistd.h>

// 简单写一下（也可以用哈希实现）
std::string SuffixToType(const std::string &suffix)
{
    if (suffix == ".html")
        return "text/html";
    else if (suffix == ".png")
        return "image/png";
    else if (suffix == ".jpg")
        return "image/jpeg";
    else
    {
        // to do
    }
    return "";
}

std::string CodetoDesc(int code)
{
    switch(code)
    {
        case 200:
            return "OK";
        case 301:
            return "Moved Permanently";
        case 307:
            return "Temporary Redirect";
        case 403:
            return "Forbidden";
        case 404:
            return "Not Found";
        case 500:
            return "Internal Server Error";
        default:
            return "Unknown";
    }
}

// 网络负责IO发送
// HandlerRequest字节流数据解析和调用业务处理方法的
// 处理报文的方法
std::string HandlerRequest(std::string &request)
{
    HttpRequest req;
    // 反序列化
    req.Deserialize(request);
    // 解析
    req.Parse();
    req.DebugHttp();
    int code = 200;

    std::string content = req.GetFileContent();
    if(content.empty())
    {
        code = 404;
        content = req.Get_404();
    }

    // 构建响应
    HttpResponse resp;
    resp.SetCode(code);
    resp.SetDesc(CodetoDesc(code));

    resp.MakeStatusLine();
    std::string content_lenn_str = "Content-Length: " + std::to_string(content.size()) + "\r\n";
    resp.AddHeader(content_lenn_str);
    std::string content_type_str = "Content-Type: " + SuffixToType(req.Suffix()) + "\r\n";
    resp.AddHeader(content_type_str);
    resp.AddContent(content);
    return resp.Serialize();

    return "";
}

// ./server port
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage: " << argv[0] << "port" << std::endl;
        return 0;
    }
    uint16_t localport = std::stoi(argv[1]);

    std::unique_ptr<TcpServer> tsvr(new TcpServer(localport, HandlerRequest));
    tsvr->Loop(); // 服务器启动

    return 0;
}